package com.zkzx.truck.service;

import com.alibaba.fastjson.JSON;
import com.zkzx.common.company.model.CompanyVO;
import com.zkzx.common.constants.SourceEnum;
import com.zkzx.common.constants.StatusEnum;
import com.zkzx.common.exception.BaseException;
import com.zkzx.common.exception.ExceptionEnum;
import com.zkzx.common.global.Global;
import com.zkzx.common.sms.constants.SmsTemplateEnum;
import com.zkzx.common.truck.command.TruckCommand;
import com.zkzx.common.truck.constants.TruckStatusEnum;
import com.zkzx.common.truck.constants.VehicleEnum;
import com.zkzx.common.truck.model.CompanyTruckVO;
import com.zkzx.common.truck.model.TruckListVO;
import com.zkzx.common.truck.model.TruckVO;
import com.zkzx.common.truck.param.TruckFilterParam;
import com.zkzx.common.truck.vo.*;
import com.zkzx.common.vo.PageResult;
import com.zkzx.common.vo.RequestFilterParams;
import com.zkzx.common.vo.StatusVO;
import com.zkzx.truck.client.CompanyClient;
import com.zkzx.truck.client.WhAdaptorClient;
import com.zkzx.truck.mapper.TruckMapper;
import com.zkzx.truck.mapper.entity.Truck;
import com.zkzx.truck.mapper.entity.TruckExample;
import com.zkzx.util.config.PrimaryMarkUtil;
import com.zkzx.util.data.CutStringUtil;
import com.zkzx.util.date.DateUtil;
import com.zkzx.util.json.JSONResultUtil;
import com.zkzx.util.sql.SQLUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.ws.rs.HttpMethod;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 北京中科智兴物联科技有限公司 @版权所有
 *
 * @Author: zhaoyihe@zkraising.com
 * @Date: 2021/05/11/15:30
 * @Description:
 */

@Slf4j
@Service
public class TruckService {

    @Resource
    private TruckMapper truckMapper;

    @Autowired
    private TruckCertificatesService truckCertificatesService;

    @Autowired
    private WhAdaptorClient whAdaptorClient;

    @Autowired
    private CompanyClient companyClient;

    /**
     * 分页查询车辆数据
     * @param filterParam 查询条件
     * @param params 分页参数
     * @return 车辆分页数据
     */
    public PageResult<TruckListVO> find(TruckFilterParam filterParam, RequestFilterParams params) {
        TruckExample truckExample = new TruckExample();
        TruckExample.Criteria criteria = truckExample.createCriteria();


        if(!StringUtils.isEmpty(filterParam.getHeaderLicense())){
            criteria.andHeaderlicenseLike(SQLUtil.valueBuildLike(filterParam.getHeaderLicense()));
        }
        if(!StringUtils.isEmpty(filterParam.getCid())){
            criteria.andCidEqualTo(filterParam.getCid());
        }
        if(!StringUtils.isEmpty(filterParam.getType())){
            criteria.andTypeEqualTo(filterParam.getType());
        }
        if(!StringUtils.isEmpty(filterParam.getStatus())){
            criteria.andStatusEqualTo(filterParam.getStatus());
        }
        if(!StringUtils.isEmpty(filterParam.getRelationNumber())){
            criteria.andRelationnumberEqualTo(filterParam.getRelationNumber());
        }
        if(!StringUtils.isEmpty(filterParam.getSource())){
            criteria.andSourceEqualTo(filterParam.getSource());
        }

        long totalNum = truckMapper.countByExample(truckExample);

        if (totalNum <= Global.ZERO){
            return new PageResult<>(params.getPage(),params.getPerPage(), Collections.emptyList(), Global.ZERO);
        }

        truckExample.setOrderByClause(params.getField().concat(" ").concat(params.getOrder()));
        truckExample.page(params.getPage()-Global.ONE , params.getPerPage());
        List<Truck> trucks = truckMapper.selectByExample(truckExample);

        List<TruckListVO> list=trucks.stream().map(truck -> TruckListVO.builder()
                .id(truck.getId())
                .cid(truck.getCid())
                .typeVO(TypeVO.builder()
                        .name(VehicleEnum.getName(truck.getType()))
                        .value(VehicleEnum.getValue(truck.getType()))
                        .build())
                .lastModifiedTime(DateUtil.convertDateToString(truck.getLastmodifiedtime()))
                .relationNumber(truck.getRelationnumber())
                .truckSourceVO(TruckSourceVO.builder()
                        .name(SourceEnum.getName(truck.getSource()))
                        .value(SourceEnum.getValue(truck.getSource()))
                        .build())
                .status(StatusVO.builder()
                        .value(TruckStatusEnum.valueOf(truck.getStatus()).name())
                        .description(TruckStatusEnum.valueOf(truck.getStatus()).getDescription())
                        .belong(belong(truck.getSource(),truck.getStatus(),HttpMethod.GET,truck.getCreatecompany(),Global.ZERO))
                        .build())
                .headerLicenseVO(HeaderLicenseVO.builder()
                                .province(CutStringUtil.getFirst(truck.getHeaderlicense()))
                                .number(CutStringUtil.getSix(truck.getHeaderlicense()))
                                 .licence(truck.getHeaderlicense())
                                .build())
                .build()).collect(Collectors.toList());

        return new PageResult<>(params.getPage(),params.getPerPage(),list, (int) totalNum);
    }


    /**
     * 根据id获取车辆详情信息
     * @param id 车辆id
     * @param companyId 企业id
     * @return 车辆详情信息
     */
    public TruckVO getById(Integer id,Integer companyId) {
        Truck truck = truckMapper.selectByPrimaryKey(id);
        if(Objects.isNull(truck)){
            return null;
        }
        TruckVO truckVO = new TruckVO();
        truckVO.setHeaderLicenseVO(HeaderLicenseVO.builder()
                    .province(CutStringUtil.getFirst(truck.getHeaderlicense()))
                    .number(CutStringUtil.getSix(truck.getHeaderlicense()))
                    .build());
        truckVO.setTailLicenseVO(TailLicenseVO.builder()
                    .province(CutStringUtil.getFirst(truck.getTaillicense()))
                    .number(CutStringUtil.getSix(truck.getTaillicense()))
                    .build());
        truckVO.setOwner(truck.getOwner());
        truckVO.setCode(truck.getCode());
        truckVO.setVolume(truck.getVolume());
        truckVO.setLicensecolor(truck.getLicensecolor());
        truckVO.setTotalWeight(truck.getTotalweight());
        truckVO.setCurbWeight(truck.getCurbweight());
        truckVO.setVerificationWeight(truck.getVerificationweight());
        truckVO.setTowWeight(truck.getTowweight());
        truckVO.setIdentify(truck.getIdentify());
        truckVO.setStatusVO(StatusVO.builder()
                .value(TruckStatusEnum.valueOf(truck.getStatus()).name())
                .description(TruckStatusEnum.valueOf(truck.getStatus()).getDescription())
                .context(truck.getRemark())
                .belong(belong(truck.getSource(),truck.getStatus(),HttpMethod.GET,truck.getCreatecompany(),companyId))
                .build());

        truckVO.setTypeVO(TypeVO.builder()
                .name(VehicleEnum.getName(truck.getType()))
                .value(VehicleEnum.getValue(truck.getType()))
                .build());

        truckVO.setTruckSourceVO(TruckSourceVO.builder()
                .name(SourceEnum.getName(truck.getSource()))
                .value(SourceEnum.getValue(truck.getSource()))
                .build());
        truckVO.setRelationNumber(truck.getRelationnumber());


        truckVO.setNature(truck.getNature());
        truckVO.setEnergyType(truck.getEnergytype());
        truckVO.setCid(truck.getCid());
        truckVO.setId(id);
        truckVO.setThreeId(truck.getThreeid());
        truckVO.setLastModifiedTime(DateUtil.convertDateToString(truck.getLastmodifiedtime()));
        truckVO.setCreateCompany(truck.getCreatecompany());

        // 运营端 和 创建该车辆的企业 才能查看所有数据信息 共享的的不允许看到敏感数据
        if (companyId.equals(Global.ZERO) ||
                StatusEnum.PRIVATE_DETAIL == belong(truck.getSource(),HttpMethod.GET,truck.getStatus(),truck.getCreatecompany(),companyId)){
         truckVO.setTruckCertificatesVO(truckCertificatesService.findVOByTruckIdId(id));
        }

        return truckVO;

    }

    /**
     * 判断归属信息
     * @param source 来源
     * @param status 当前状态
     * @param method 方法
     * @param createCompany 创建企业
     * @param company 当前企业
     * @return true 属于当前企业 false 不属于当前企业
     */
    private StatusEnum belong(String source, String status, String method, Integer createCompany, Integer company){
        // 判断来源是否属于网货
        if(SourceEnum.SHARE.name().equals(source)){
            // 审核中 或者 审核失败  等 跳转失败提示页面
            if(TruckStatusEnum.APPROVE_ING.name().equals(status) || TruckStatusEnum.APPROVE_FAIL.name().equals(status)){
                return StatusEnum.REASON;
            }

            // 审核成功 跳转详情页面
            return StatusEnum.PUBLIC_DETAIL;

        }

        // 判断自建是否是当前企业建立

        // 如果信息不存在 并且是新增请求 跳转录入页面  并且是当前企业录入
        if(TruckStatusEnum.NO_SUBMIT.name().equals(status) &&  HttpMethod.POST.equals(method)&&createCompany.equals(company)){
            return StatusEnum.INPUT;
        }

        // 未提交  审核中  审核失败 审核 成功 但是 当前登录企业  = 数据初始企业
        if (createCompany.equals(company)){
            return StatusEnum.PRIVATE_DETAIL;
        }

        // 存在 跳转详情页面
        return StatusEnum.PUBLIC_DETAIL;
    }



    /**
     * 新增车辆信息
     * @param command 入参
     * @param userId 用户id
     */
    public StatusVO add(TruckCommand command, int userId){

        TruckExample truckExample = new TruckExample();
        truckExample.createCriteria().andHeaderlicenseEqualTo(command.getHeaderLicenseVO().getLicence());

        Optional<Truck> trucks = truckMapper.selectByExample(truckExample).stream().findFirst();
        if(trucks.isPresent()){

            // 如果车辆存在 需要将车辆关系企业数进行累计
            Truck truck = trucks.get();

            // 先进行交易 是否已有数据 防止重复录入
            List<CompanyTruckVO> vos = companyClient.getByTruckIdCompanyId(truck.getId(), command.getCompanyId());
            if (CollectionUtils.isNotEmpty(vos)){
                throw new BaseException(ExceptionEnum.TRUCK_CODD_ERROR.getCode(),ExceptionEnum.TRUCK_CODD_ERROR.getMsg());
            }

            Integer relationNumber = Integer.parseInt(truck.getRelationnumber()) + Global.ONE;
            truck.setRelationnumber(relationNumber.toString());
            truckMapper.updateByPrimaryKeySelective(truck);

            return StatusVO.builder().id(truck.getId()).value(TruckStatusEnum.valueOf(truck.getStatus()).name())
                    .description(TruckStatusEnum.valueOf(truck.getStatus()).getDescription())
                    .belong(belong(truck.getSource(),truck.getStatus(), HttpMethod.POST, truck.getCreatecompany(),command.getCompanyId())).build();
        }

        Truck truck = new Truck();
        // 需要随机生成登录码 setaqy + 年份两位+月+日+随机四位数
        truck.setCid(PrimaryMarkUtil.getCLMark());
        truck.setCode(command.getCode());
        truck.setHeaderlicense(command.getHeaderLicenseVO().getLicence());
        truck.setSource(StringUtils.isEmpty(command.getSource()) ? SourceEnum.SHARE.name(): command.getSource());
        truck.setStatus(TruckStatusEnum.NO_SUBMIT.name());
        truck.setRelationnumber(Global.ONE.toString());

        truck.setCreatecompany(command.getCompanyId());
        truck.setCreatetime(new Date());
        truck.setLastmodifiedtime(new Date());
        truck.setCreateuser(userId);
        truck.setLastmodifieduser(userId);
        truckMapper.insert(truck);
        Optional<Truck> first = truckMapper.selectByExample(truckExample).stream().findFirst();
        Integer id = 0;
        if(first.isPresent()){
            id= first.get().getId();
        }

        TruckCommand truckCommand;
        try{
            truckCommand = whAdaptorClient.getTruck(id, command.getHeaderLicenseVO().getLicence());
        }catch (Exception e){
            truckMapper.deleteByPrimaryKey(id);
            throw new BaseException(ExceptionEnum.WH_DATA_ERROR.getCode(), ExceptionEnum.WH_DATA_ERROR.getMsg());
        }

        if(Objects.isNull(truckCommand)){
            truckMapper.deleteByPrimaryKey(id);
            throw new BaseException(ExceptionEnum.TRUCK_WH_ERROR.getCode(), ExceptionEnum.TRUCK_WH_ERROR.getMsg());
        }

        this.update(truckCommand,id,userId);
        String source = Optional.ofNullable(truckCommand.getSource()).orElse(truck.getSource());
        return StatusVO.builder().id(id).value(TruckStatusEnum.valueOf(truckCommand.getStatus()).name())
                .description(TruckStatusEnum.valueOf(truckCommand.getStatus()).getDescription())
                .belong(belong(source,truckCommand.getStatus(),HttpMethod.POST,truck.getCreatecompany(),command.getCompanyId())).build();
    }


    /**
     * 更新车辆信息
     * @param command 入参
     * @param id 车辆id
     * @param userId 操作人员id
     */
    public void update(TruckCommand command, Integer id, int userId) {

        Truck truck = new Truck();
        truck.setId(id);
        truck.setThreeid(command.getThreeId());
        truck.setCode(command.getCode());
        truck.setOwner(command.getOwner());
        truck.setTaillicense(Optional.ofNullable(command.getTailLicenseVO()).map(TailLicenseVO::getLicence).orElse(null));
        truck.setLicensecolor(command.getLicensecolor());
        truck.setType(command.getType());
        truck.setEnergytype(command.getEnergyType());
        truck.setVolume(command.getVolume());
        truck.setTotalweight(command.getTotalWeight());
        truck.setCurbweight(command.getCurbWeight());
        truck.setVerificationweight(command.getVerificationWeight());
        truck.setTowweight(command.getTowWeight());
        truck.setIdentify(command.getIdentify());
        truck.setNature(command.getNature());
        truck.setStatus(command.getStatus());
        truck.setLastmodifiedtime(new Date());
        truck.setRemark(command.getRemark());
        truck.setLastmodifieduser(userId);
        truck.setSource(command.getSource());

        TruckExample truckExample = new TruckExample();
        truckExample.createCriteria().andIdEqualTo(id);

        truckMapper.updateByExampleSelective(truck,truckExample);
        truckCertificatesService.insertOrUpdateByVO(command.getTruckCertificatesVO(),id);


    }

    /**
     * 添加车辆信息
     * @param id 车辆id
     * @param companyThreeId 企业三方id
     * @param companyId 企业id
     * @param userId 用户id
     */

     public StatusVO submit(Integer id, String companyThreeId,Integer companyId, Integer userId){
         TruckVO truckVO = this.getById(id, companyId);
         if(Objects.isNull(truckVO.getTruckCertificatesVO()) ||StringUtils.isEmpty(truckVO.getIdentify()) ){
             throw new BaseException(ExceptionEnum.SUBMIT_COMPLETE_ERROR.getCode(),ExceptionEnum.SUBMIT_COMPLETE_ERROR.getMsg());
         }
         TruckCommand truckCommand = whAdaptorClient.add(id, companyThreeId, truckVO);
         this.update(truckCommand,id,userId);

         String status = Optional.ofNullable(truckCommand.getStatus()).orElse(truckVO.getStatusVO().getValue());

         return StatusVO.builder().id(id).value(TruckStatusEnum.valueOf(status).name())
                 .description(TruckStatusEnum.valueOf(status).getDescription()).build();

     }


    /**
     * 更新车辆网货对接状态
     * @param vo 车辆信息
     */
    public void updateToWh(TruckListVO vo){
        Truck truck = truckMapper.selectByPrimaryKey(vo.getId());
        if(StringUtils.isEmpty(truck.getThreeid())){
            return;
        }
        //查询车辆审核状态
        TruckCommand truckCommand = whAdaptorClient.getStatus(vo.getId(), truck.getThreeid());
        log.info("查询状态网货返回数据：{}", JSONResultUtil.object2JSON(truckCommand));
        if (TruckStatusEnum.VERIFY_SUCCESS.name().equals(truckCommand.getStatus())){
            this.update(truckCommand,vo.getId(),Global.ZERO);
            companyClient.updateTruck(truckCommand,Global.ZERO);
            //发送短信通知
            //查询公司信息
            CompanyVO companyVO = companyClient.getById(truck.getCreatecompany());
            this.sendTruckSms(truckCommand.getStatus(),companyVO.getMemberMobile(),companyVO.getName(),truck.getHeaderlicense());
        }
    }

    /**
     * 车辆审核短信通知
     * @param status  车辆状态
     * @param mobile 公司联系人手机号
     * @param companyName 公司名称
     * @param LicensePlate 车牌号
     */
    public void sendTruckSms(String status,String mobile,String companyName,String LicensePlate){
        Map<String, String> parameterMap = new HashMap<>();
        //审核成功和审核失败传参一致
        parameterMap.put(SmsTemplateEnum.TRUCK_EXAMINE_SUCCESS.getParameterArr()[Global.ZERO],companyName);
        parameterMap.put(SmsTemplateEnum.TRUCK_EXAMINE_SUCCESS.getParameterArr()[Global.ONE],LicensePlate);
        if (TruckStatusEnum.VERIFY_SUCCESS.name().equals(status)){
            //已验证
            companyClient.sendSms(mobile, SmsTemplateEnum.TRUCK_EXAMINE_SUCCESS.getTemplate(), JSON.toJSONString(parameterMap));
        }else if (TruckStatusEnum.APPROVE_FAIL.name().equals(status)){
            //审核驳回
            companyClient.sendSms(mobile, SmsTemplateEnum.TRUCK_EXAMINE_FAIL.getTemplate(), JSON.toJSONString(parameterMap));
        }
    }
}


